﻿using AxureRPVersionSelector.Configs;

using Emergen.Framework.Logger;

using System.Diagnostics;

namespace AxureRPVersionSelector
{
    /// <summary>
    /// 
    /// </summary>
    public class AxureRPVersionSelector
    {
        /// <summary>
        /// 
        /// </summary>
        private AxureRPVersionSelector() { }

        /// <summary>
        /// 
        /// </summary>
        public static AxureRPVersionSelector Instance => new AxureRPVersionSelector();

        /// <summary>
        /// 打开文件
        /// </summary>
        /// <param name="filename"></param>
        /// <exception cref="FileNotFoundException"></exception>
        public void OpenFile(string filename)
        {
            try
            {
                if (!File.Exists(filename))
                {
                    throw new FileNotFoundException($"{filename} => 对应文件不存在.");
                }
                if (!CheckFileExt(filename))
                {
                    throw new FileNotFoundException($"{filename} => 不是AxureRP所支持的文件扩展名.");
                }

                var res = false;
                var appList = ConfigManager.Instance.AppList;
                foreach (var version in appList.Keys)
                {
                    var appinfo = appList[version];
                    if(CheckFileVersion(appinfo, filename))
                    {
                        DoOpen(appinfo, filename);
                        res = true;
                        break;
                    }
                }
                if (res)
                {
                    throw new FileNotFoundException($"{filename} => 未找到可用的AxureRP版本.");
                }
            }
            catch (Exception ex)
            {
                Logs.Instance.Error(ex);
            }
        }

        private void DoOpen(AppInfoEntity appinfo, string filename)
        {
            var path = appinfo.Path;
            var args = string.Format(appinfo.ParamsPattern, filename);
            var psi = new ProcessStartInfo(path, args);
            Process.Start(psi);
        }

        /// <summary>
        /// 检查扩展名是否正确
        /// </summary>
        /// <param name="filename"></param>
        /// <returns></returns>
        private bool CheckFileExt(string filename)
        {
            try
            {
                var fileExt = Path.GetExtension(filename);
                if (ConfigManager.Instance.ExtList.Contains(fileExt))
                {
                    return true;
                }
                else
                {
                    return false;
                }
            }
            catch (Exception ex)
            {
                Logs.Instance.Error(ex);
                return false;
            }
        }

        /// <summary>
        /// 检查AxureRP文件版本
        /// </summary>
        /// <param name="filename"></param>
        /// <returns></returns>
        private bool CheckFileVersion(AppInfoEntity appinfo, string filename)
        {
            using (var fs = File.OpenRead(filename))
            {
                try
                {
                    var fvp = appinfo.FileVersionPostion;
                    var offset = fvp?.Offset ?? 0;
                    var length = fvp?.Length ?? -1;

                    if (length <= 0) return false;

                    var buffer = new byte[length];
                    if (fs.Length < length) return false;
                    fs.Read(buffer, offset, length);

                    var res = buffer.SequenceEqual(appinfo.Flag);
                    return res;
                }
                catch (Exception ex)
                {
                    Logs.Instance.Error(ex);
                    return false;
                }
                finally
                {
                    fs?.Close();
                }
            }
        }

    }
}
